package com.ruoyi.points.dao.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.utils.CodeGeneratorUtil;
import com.ruoyi.points.dao.IPointsChangeRecordDao;
import com.ruoyi.points.domain.PointsChangeRecord;
import com.ruoyi.points.mapper.PointsChangeRecordMapper;
import com.ruoyi.system.mapper.UserAdditionalInfoMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;


@Repository
@RequiredArgsConstructor
public class PointsChangeRecordDaoImpl
        extends ServiceImpl<PointsChangeRecordMapper, PointsChangeRecord>
        implements IPointsChangeRecordDao {

    @Autowired
    private PointsChangeRecordMapper recordMapper;

    @Autowired
    private UserAdditionalInfoMapper  userMapper;

    /**
     * 记录积分变动并更新用户积分
     *
     * @param userId 用户ID
     * @param pointsChange 积分变化值（正数增加，负数减少）
     * @param changeSourceType 变动来源类型
     * @param batchCode 批次编码，可选参数，如果为null则不设置批次编码
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int recordAndUpdatePoints(Long userId,
                                     Long pointsChange,
                                     Long changeSourceType,
                                     String batchCode) {

        // 1. 获取原积分（加行锁）
        Long before = userMapper.selectCurrentPointsForUpdate(userId);
        if (before == null) return 0;

        // 2. 计算新的积分（防止为负）
        long after = Math.max(before + pointsChange, 0);

        // 3. 插入变动记录
        PointsChangeRecord record = new PointsChangeRecord();
        record.setUserId(userId);
        record.setPointsChange(pointsChange);
        record.setPointsBefore(before);
        record.setPointsAfter(after);
        record.setChangeSourceType(changeSourceType);
        record.setRecordCode(CodeGeneratorUtil.generateCode());
        // 只在有传入批次编码时才设置，没有则为空
        if (batchCode != null && !batchCode.isEmpty()) {
            record.setBatchCode(batchCode);
        }

        if (recordMapper.insertPointsChangeRecord(record) == 0) return 0;

        // 4. 根据来源决定是否更新 total_points
        boolean affectTotal = !changeSourceType.equals(7L); // 7 = 商品退货，不累计总积分

        // 5. 更新用户积分
        return userMapper.updateUserPoints(userId, pointsChange, affectTotal);
    }

}
